Sqlite中的页面类型包括: 叶子页面(leaf):存储数据; 内部页面(internal): 包含查询时的导航信息; 溢出页面(overflow); 空闲页面(free); (1). file header 文件以1号页面开始,它包括100个字节的文件头。 Header string(头字符串):16个字节,"SQLite format 3." Page size(页面大小):1024 File format(文件格式):在当前的版本都为1。 Reserved space(保留空间):1个字节,SQLite在每个页面的末尾都会保留一定的空间,留作它用,默认为0。 Embedded payload:max embedded payload fraction(偏移21)的值限定了B树内节点(页面)中一个元组(记录,单元)最多能够使用的空间。255意味着100%,默认值为0x40,即64(25%),这保证了一个结点(页面)至少有4个单元。如果一个单元的负载(payload,即数据量)超过最大值,则溢出的数据保存到溢出的页面,一旦SQLite分配了一个溢出页面,它会尽可能多的移动数据到溢出页面,下限为min embedded payload fraction value(偏移为22),默认的值为32,即12.5% 。 File change counter(文件修改计数):通常被事务使用,它由事务增加其值。该值的主要目的是数据库改变时,pager避免对缓存进行刷盘。 Freelist(空闲页面链表):在文件头偏移32的4个字节记录着空闲页面链的第一个页面,偏移36处的4个字节为空闲页面的数量。 空闲页面分为两种页面:trunk pages(主页面)和leaf pages(叶子页面)。文件头的指针指向空闲链表的第一个trunk page,每个trunk page指向多个叶子页面。 Trunk page的格式如下,从页面的起始处开始: 4个字节,指向下一个trunk page的页面号; 4个字节,该页面的叶子页面指针的数量; 指向叶子页面的页面号,每项4个字节。 Meta variables(元数据变量): 从偏移为40开始,为15个4字节的元数据变量,这些元数据主要与B树和VM有关。 (2). 读取file 程序调用API sqlite3_open打开数据库文件时,SQLite就会读取文件头进行数据库的初始化。 数据库文件页的可复写条件: ①在事务开始的时候,页面的源文件就应该被写入回滚日志并同步。 ②pager在事务开始的时候是freelist的叶子页面。 ③在事务开始的时候,页码要大于数据库文件中的最大页。 当然数据库文件页也有一些不可复写的,除了①某个页面同其他页面在同一个扇区。②原子页的写优化是可行的,整个事务除了事务序列号的更新,都由一个单一的页变化组成。